package org.dairy.farms.nandana.core.security.userdetails;

import org.dairy.farms.dao.FarmDAO;
import org.dairy.farms.dao.PersonDAO;
import org.dairy.farms.dao.RoleTypeDAO;
import org.dairy.farms.model.Farm;
import org.dairy.farms.model.Person;
import org.dairy.farms.model.RoleType;
import org.dairy.farms.nandana.exception.FunctionalityException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * Created by IntelliJ IDEA.
 * User: gduggira
 * Date: Jun 17, 2011
 * Time: 4:59:45 PM
 */
public class NandanaUserDetailsService implements UserDetailsService {
    @Autowired
    PersonDAO personDAO;
    @Autowired
    RoleTypeDAO roleTypeDAO;
    @Autowired
    FarmDAO farmDAO;
    private static final Logger logger = LoggerFactory.getLogger(NandanaUserDetailsService.class);

    @Transactional(propagation = Propagation.REQUIRED)
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
        logger.debug("Received user name as :"+userName+" Should start populating the user details service.");
        List<Person> personsList = personDAO.findByProperty("emailAddress",userName);
        if(personsList == null || personsList.size()<=0){
            throw new UsernameNotFoundException(userName + "not found");
        }
        if(personsList.size()>1){
            throw new FunctionalityException("More than one user name found, functionality exception");
        }
        NandanaUserDetails nandanaUserDetails = populateUserDetails(personsList);
        return nandanaUserDetails;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    private NandanaUserDetails populateUserDetails(List<Person> personsList) {
        NandanaUserDetails nandanaUserDetails = null;
        Person person = personsList.get(0);
        if(person!=null){
            nandanaUserDetails = new NandanaUserDetails(person.getEmailAddress(),person.getPassword(),
                                                person.isEnabled(),true,true,true, person.getId());
            Set<RoleType> roleTypes = person.getRoles();
            Farm farm = farmDAO.findById(person.getFarm().getId());
            for(RoleType roleType:roleTypes){
                RoleType personRoleType = roleTypeDAO.findById(roleType.getId());
                NandanaGrantedAuthorityImpl nandanaGrantedAuthority = new NandanaGrantedAuthorityImpl(personRoleType.getName(),
                                        farm.getName(),person.getFarm().getId());
                nandanaUserDetails.addAuthority(nandanaGrantedAuthority);
            }
        }
        return nandanaUserDetails;
    }

}
